package token

import (
	"crypto/rsa"
	"github.com/golang-jwt/jwt/v4"
	"io/ioutil"
	"os"
	"time"
)

type jwtTokenGenerator struct {
	privateKeyPath string
	expiresTime    int32
	issue          string
	nowFunc        func() time.Time
}

func NewJwtTokenGenerator(privateKeyPath string, expiresTime int32, issue string) *jwtTokenGenerator {
	return &jwtTokenGenerator{privateKeyPath, expiresTime, issue, time.Now}
}

func (t *jwtTokenGenerator) GenerateToken(accountId string) (token string, expiresTime int32, err error) {

	expiresTime = t.expiresTime

	newSec := t.nowFunc()

	tkn := jwt.NewWithClaims(jwt.SigningMethodRS512, jwt.RegisteredClaims{
		Issuer: t.issue,
		IssuedAt: &jwt.NumericDate{
			Time: newSec,
		},
		ExpiresAt: &jwt.NumericDate{
			Time: time.Unix(newSec.Unix()+int64(expiresTime), 0),
		},
		Subject: accountId,
	})

	file, err := os.Open(t.privateKeyPath)

	if err != nil {
		return "", expiresTime, err
	}

	b, err := ioutil.ReadFile(file.Name())

	if err != nil {
		return "", expiresTime, err
	}

	var rsaPSSKey *rsa.PrivateKey
	if rsaPSSKey, err = jwt.ParseRSAPrivateKeyFromPEM(b); err != nil {
		return "", expiresTime, err
	}

	tokenString, err := tkn.SignedString(rsaPSSKey)

	if err != nil {
		return "", expiresTime, err
	}

	return tokenString, expiresTime, nil

}
